package com.itheima.health.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.health.dao.MemberDao;
import com.itheima.health.dao.OrderDao;
import com.itheima.health.dao.OrdersettingDao;
import com.itheima.health.exception.MyException;
import com.itheima.health.pojo.Member;
import com.itheima.health.pojo.Order;
import com.itheima.health.pojo.OrderSetting;
import com.itheima.health.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 预约
 * @Author: HuChunping
 * @Date: 2021/01/16
 **/
@Service(interfaceClass = OrderService.class)
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderDao orderDao;

    @Autowired
    private MemberDao memberDao;

    @Autowired
    private OrdersettingDao ordersettingDao;


    /**
     * 预约提交
     * @Author: HuChunping
     * @Date: 2021/1/16 22:45
     * @param orderInfo: 前端传的体检人信息数据，用map封装
     * @return: com.itheima.health.pojo.Order
     **/
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Order submitOrder(Map<String, String> orderInfo) {
        // 获取前端传的预约信息的日期
        String orderDateStr = orderInfo.get("orderDate");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Date orderDate=null;
        try {
            // 按指定的格式去格式化日期
            orderDate = sdf.parse(orderDateStr);
        } catch (ParseException e) {
            throw new MyException("日期格式错误");
        }
        //=======================通过日期查询当天是否有预约设置，如果没有，则当天不能预约
        OrderSetting osInDB = ordersettingDao.findByOrderDate(orderDate);
        if (osInDB != null) {
            // 预约人数大于最大预约人数
            if (osInDB.getReservations() >= osInDB.getNumber()) {
                throw new MyException("预约人数已达上限，请选择其他日期");
            }
        } else {
            throw new MyException("所选日期不能预约，请选择其他日期");
        }
        //========================查询会员是否注册，如果没有自动注册为会员，如果是会员判断是否重复预约
        String telephone = orderInfo.get("telephone");
        Member member = memberDao.findByTelephone("telephone");
        // 创建订单便于下面使用
        Order order = new Order();
        // 订单部分套餐参数设置
        String setmealId = orderInfo.get("setmealId");
        order.setSetmealId(Integer.valueOf(setmealId));
        order.setOrderDate(orderDate);
        if (member==null) {
            Member newMember = new Member();
            newMember.setName(orderInfo.get("name"));
            newMember.setSex(orderInfo.get("sex"));
            newMember.setIdCard(orderInfo.get("idCard"));
            newMember.setPhoneNumber(telephone);
            newMember.setRegTime(new Date());
            // 取手机号的后六位做密码(从第5位开始截取)
            newMember.setPassword(telephone.substring(5));
            newMember.setRemark("微信预约自动注册");
            memberDao.add(newMember);
            // 查询后设置用户id
            order.setMemberId(newMember.getId());
        } else {
            // 已经是会员，判断是否重复预约
            // String setmealId = orderInfo.get("setmealId");
            Integer memberId = member.getId();
            // 设置订单的套餐参数,便于下面查询是否重复预约
            // order.setSetmealId(Integer.valueOf(setmealId));
            // 如果不是会员，则memberId为空，所以不能写在上面
            order.setMemberId(memberId);
            // order.setOrderDate(orderDate);
            // 通过用户memberId，预约日期orderDate，预约套餐：判断用户是否同一天预约同一套餐
            List<Order> orderList = orderDao.findByCondition(order);
            // 如果有值，说明重复预约
            if (!StringUtils.isEmpty(orderList)) {
                throw new MyException("不能重复预约");
            }
        }
        //=======================可以预约
        // 设置memberId: 如果是新用户注册，则需要注册后查询(否则为空)，如果老用户，直接查询，所以只能这里单独查询
        // order.setMemberId(member.getId()); // 写在用户注册上了

        // 设置用户预约信息
        order.setOrderType(orderInfo.get("orderType"));
        // 更新已预约人数,只有osInDB有值才能更新
        // ！！！！！！！！！在多线程分布式中需要做下列判断(用户端预约对公共资源的添加)，在sql层也增加了判断
        int count = ordersettingDao.editReservationsByOrderDate(osInDB);
        if (count==0){
            throw new MyException("所选日期预约已满，请选择其他日期");
        }
        // 未到诊
        order.setOrderStatus(Order.ORDERSTATUS_NO);
        // 只有数据库更新成功才能添加订单
        orderDao.add(order);
        return order;
    }

    /**
     * 查询预约订单信息
     * @Author: HuChunping
     * @Date: 2021/1/17 21:54
     * @param id: 套餐id
     * @return: java.util.Map<java.lang.String,java.lang.String>
     **/
    @Override
    public Map<String, String> findById(int id) {
        Map order = orderDao.findById4Detail(id);
        return order;
    }
}




















